package com.vincent.tvui;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;

import java.io.InputStream;
import java.util.Map;

/**
 * 现实现表格布局
 */
public class CellLayout extends ViewGroup implements CellView {

    private static final String TAG = "CellLayout";

    private boolean mDebug = false;

    //单元格的模式，square单元格是正方形，normal单元根据计算
    public final static int CELL_MODE_NORMAL = 0;
    public final static int CELL_MODE_SQUARE = 1;

    private final static int NO_CELL_SIZE = -1;

    //单元格间隙
    private int mWidthGap;
    private int mHeightGap;

    //单元格大小
    private int mCellSize = NO_CELL_SIZE;

    //单元格个数
    private int mRowCellCnt = 0;
    private int mColumnCellCnt = 0;

    //单元格宽高,如果设置了mCellSize则使用CellSize为标准，未设置则使用cellCount计算获得
    private int mCellWith;
    private int mCellHeight;

    private int mCellMode = CELL_MODE_NORMAL;

    private CellLayoutInflater mCellLayoutInflater;

    private Paint mPt;

    private CellViewController mCellViewController;
    private CellClickListener mCellClickListener;

    public CellLayout(Context context) {
        this(context, null, 0);
    }

    public CellLayout(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CellLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CellLayout, defStyleAttr, 0);
        mWidthGap = a.getDimensionPixelSize(R.styleable.CellLayout_widthGap, 0);
        mHeightGap = a.getDimensionPixelSize(R.styleable.CellLayout_heightGap, 0);
        mCellSize = a.getDimensionPixelSize(R.styleable.CellLayout_cellSize, NO_CELL_SIZE);
        mRowCellCnt = a.getInt(R.styleable.CellLayout_rowCell, 0);
        mColumnCellCnt = a.getInt(R.styleable.CellLayout_columnCell, 0);
        mCellMode = a.getInt(R.styleable.CellLayout_cellMode, CELL_MODE_NORMAL);
        mDebug = a.getBoolean(R.styleable.CellLayout_debug, false);
        a.recycle();

        setWillNotDraw(false);
        initCellLayout(context);
    }

    public CellLayout(Context context, Map<String, String> styles) {
        super(context);
    }

    //初始化CellLayout
    private void initCellLayout(Context context) {
    }

    @Override
    protected boolean addViewInLayout(View child, int index, LayoutParams params) {
        if (child != null) {
            child.setOnClickListener(mCellClickListener);
        }
        return super.addViewInLayout(child, index, params);
    }

    public void setCellClickListener(CellClickListener cellClickListener) {
        mCellClickListener = cellClickListener;
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
    }

    @Override
    protected CellLayoutParams generateDefaultLayoutParams() {
        return new CellLayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
    }

    @Override
    public CellLayoutParams generateLayoutParams(AttributeSet attrs) {
        return new CellLayoutParams(getContext(), attrs);
    }

    public int getCellMode() {
        return mCellMode;
    }

    /**
     * 设置单元格模式
     *
     * @param cellMode one of {@link #CELL_MODE_NORMAL}, {@link #CELL_MODE_SQUARE}.
     */
    public void setCellMode(int cellMode) {
        mCellMode = cellMode;
        requestLayout();
    }

    public int getCellSize() {
        return mCellSize;
    }

    public void setCellSize(int cellSize) {
        mCellSize = cellSize;
        requestLayout();
    }


    public void setGap(int widthGap, int heightGap) {
        this.mWidthGap = widthGap;
        this.mHeightGap = heightGap;
        requestLayout();
    }

    public void setCellCount(int rowCell, int columnCell) {
        this.mRowCellCnt = rowCell;
        this.mColumnCellCnt = columnCell;
        requestLayout();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec);
        int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);

        int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec);
        int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);

        /*if (widthSpecMode == MeasureSpec.UNSPECIFIED
                || heightSpecMode == MeasureSpec.UNSPECIFIED) {
            throw new RuntimeException(
                    "CellLayout cannot have UNSPECIFIED dimensions");
        }*/

        if (mCellSize == NO_CELL_SIZE && (mColumnCellCnt == 0 || mRowCellCnt == 0)) {
            throw new IllegalArgumentException("must set cell size or cell count!");
        }

        if (mCellMode == CELL_MODE_NORMAL) {
            mCellHeight = (int) ((heightSpecSize - getPaddingTop()
                    - getPaddingBottom() - (mRowCellCnt + 1) * mHeightGap)
                    / (1.0 * mRowCellCnt) + 0.5f);
            mCellWith = (int) ((widthSpecSize - getPaddingLeft()
                    - getPaddingRight() - (mColumnCellCnt + 1) * mWidthGap)
                    / (1.0 * mColumnCellCnt) + 0.5f);
        } else if (mCellMode == CELL_MODE_SQUARE) {
            mCellHeight = mCellWith = mCellSize;
        }

        int newWidth = 0;
        int childCount = getChildCount();
        for (int i = 0; i < childCount; i++) {
            View child = getChildAt(i);
            if (child == null || child.getVisibility() == GONE)
                continue;
            CellLayout.CellLayoutParams lp = (CellLayout.CellLayoutParams) child.getLayoutParams();
            measureChild(child, lp);
            newWidth = Math.max(newWidth, lp.x + lp.width);//最右侧宽度
        }

        newWidth += getPaddingLeft() + getPaddingRight();
        newWidth = Math.max(widthSpecSize, newWidth);

        //正方形时，计算单元隔个数
        if (mCellMode == CELL_MODE_SQUARE) {
            mColumnCellCnt = (newWidth - mWidthGap - getPaddingLeft() - getPaddingRight()) / (mCellWith + mWidthGap);
            mRowCellCnt = (heightSpecSize - mHeightGap - getPaddingTop() - getPaddingBottom()) / (mCellHeight + mHeightGap);
        }

        setMeasuredDimension(newWidth,
                resolveSize(heightSpecSize, heightMeasureSpec));
    }

    //计算子控件大小
    public void measureChild(View child, CellLayout.CellLayoutParams lp) {
        lp.setup(mCellWith, mCellHeight, mWidthGap, mHeightGap, getPaddingLeft(), getPaddingTop());
        int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(lp.width,
                MeasureSpec.EXACTLY);
        int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(lp.height,
                MeasureSpec.EXACTLY);
        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                CellLayout.CellLayoutParams lp = (CellLayout.CellLayoutParams) child
                        .getLayoutParams();
                int childLeft = lp.x;
                int childTop = lp.y;
                child.layout(childLeft, childTop, childLeft + lp.width,
                        childTop + lp.height);
            }
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if (mDebug) {
            Log.d(TAG, "onDraw Enter");
            if (mPt == null) {
                mPt = new Paint();
                mPt.setAntiAlias(true);
                mPt.setColor(Color.BLUE);
                mPt.setStyle(Paint.Style.STROKE);
            }

            int tmpLeft = getPaddingLeft();
            int tmpTop = getPaddingTop();
            int tmpRight = mColumnCellCnt * mCellWith + (mColumnCellCnt + 1) * mWidthGap + getPaddingLeft();
            int tmpBottom = mRowCellCnt * mCellHeight + (mRowCellCnt + 1) * mHeightGap + getPaddingTop();

            //最外层
            canvas.drawRect(tmpLeft, tmpTop, tmpRight, tmpBottom, mPt);
            for (int m = 0; m < mColumnCellCnt; m++) {
                tmpLeft = getPaddingLeft() + m * mCellWith + (m + 1) * mWidthGap;
                tmpRight = tmpLeft + mCellWith;
                for (int n = 0; n < mRowCellCnt; n++) {
                    tmpTop = getPaddingTop() + n * mCellHeight + (n + 1) * mHeightGap;
                    tmpBottom = tmpTop + mCellHeight;
                    canvas.drawRect(tmpLeft, tmpTop, tmpRight, tmpBottom, mPt);
                }
            }
        }

        super.onDraw(canvas);
    }

    public void inflate(InputStream inputStream) {
        mCellLayoutInflater = CellLayoutInflater.getInstance();
        if (mCellViewController != null) {
            mCellLayoutInflater.setCellViewController(mCellViewController);
        }
        mCellLayoutInflater.inflate(inputStream, this);
    }

    public void setRowCellCount(int rowCellCount) {
        mRowCellCnt = rowCellCount;
        requestLayout();
    }

    public void setColumnCellCount(int columnCellCount) {
        mColumnCellCnt = columnCellCount;
        requestLayout();
    }

    public void setWidthGap(int widthGap) {
        mWidthGap = widthGap;
        requestLayout();
    }

    public void setHeightGap(int heightGap) {
        mHeightGap = heightGap;
        requestLayout();
    }

    public void setDebug(boolean debug) {
        mDebug = debug;
        postInvalidate();
    }

    @Override
    public View focusSearch(int direction) {
        return super.focusSearch(direction);
    }

    @Override
    public View focusSearch(View focused, int direction) {
        return super.focusSearch(focused, direction);
    }

    @Override
    public void setStyles(Map<String, String> styles) {

    }

    @Override
    public void setController(CellViewController controller) {
        this.mCellViewController = controller;
    }

    public static class CellLayoutParams extends MarginLayoutParams {
        public int cellX = 0;
        public int cellY = 0;
        public int spanX = 1;
        public int spanY = 1;
        int x = 0;
        int y = 0;

        public CellLayoutParams(Context c, AttributeSet attrs) {
            super(c, attrs);
            TypedArray a = c.obtainStyledAttributes(attrs, R.styleable.CellLayout);
            for (int i = 0; i < a.getIndexCount(); i++) {
                int attr = a.getIndex(i);
                if (attr == R.styleable.CellLayout_spanY) {
                    spanY = a.getInt(attr, spanY);
                    if (spanY < 1) {
                        spanY = 1;
                    }
                } else if (attr == R.styleable.CellLayout_spanX) {
                    spanX = a.getInt(attr, spanX);
                    if (spanX < 1) {
                        spanX = 1;
                    }
                } else if (attr == R.styleable.CellLayout_cellX) {
                    cellX = a.getInt(attr, cellX);
                    if (cellX < 0) {
                        cellX = 0;
                    }
                } else if (attr == R.styleable.CellLayout_cellY) {
                    cellY = a.getInt(attr, cellY);
                    if (cellY < 0) {
                        cellY = 0;
                    }
                }
            }

            a.recycle();
        }

        public CellLayoutParams(int width, int height) {
            super(width, height);
        }

        public CellLayoutParams(MarginLayoutParams source) {
            super(source);
        }

        public CellLayoutParams(LayoutParams source) {
            super(source);
        }

        //设置布局参数值
        public void setup(int cellWidth, int cellHeight, int widthGap, int heightGap, int paddingLeft, int paddingTop) {
            final int myCellSpanX = spanX;
            final int myCellSpanY = spanY;
            final int myCellX = cellX;
            final int myCellY = cellY;

            width = myCellSpanX * cellWidth + ((myCellSpanX - 1) * widthGap) - leftMargin - rightMargin;
            height = myCellSpanY * cellHeight + ((myCellSpanY - 1) * heightGap) - topMargin - bottomMargin;
            x = paddingLeft + leftMargin + myCellX * cellWidth + (myCellX + 1) * widthGap;
            y = paddingTop + topMargin + myCellY * cellHeight + (myCellY + 1) * heightGap;
        }
    }


    public interface CellClickListener extends OnClickListener {

    }

}
